from rest_framework import serializers
from api import models
from django.forms import model_to_dict
from django.db.models import Max

class NewsDetailModelSerializer(serializers.Serializer):
    key = serializers.CharField()
    cos_path = serializers.CharField()

class NewsDetailModelSerializer(serializers.ModelSerializer):
    images = NewsDetailModelSerializer(many=True)  # 传入一个字典images,包含了key和cos_path
    token = serializers.CharField()
    topic_id = serializers.CharField()

    class Meta:
        model = models.News
        exclude = ["user", "viewer_count", "comment_count", "favor_count"]

    def create(self, validated_data):
        image_list = validated_data.pop('images')
        # 获取用户信息
        token = validated_data.pop('token')
        user_object = models.UserInfo.objects.filter(token=token).first()
        validated_data['user'] = user_object
        # 保存到News表中
        news_object = models.News.objects.create(**validated_data)
        # 保存到NewsDetail表中(通过bulk_create获取对象列表一并添加)
        data_object = models.NewsDetail.objects.bulk_create(
            [models.NewsDetail(**info, news=news_object) for info in image_list]
        )
        # 将参数返回(必须将定义了的值返回)
        news_object.images = data_object
        news_object.token = token
        if news_object.topic:
            news_object.topic.count += 1
            news_object.save()

        return news_object


class NewsModelSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    topic = serializers.SerializerMethodField()

    class Meta:
        model = models.News
        fields = "__all__"

    def get_user(self, obj):
        # 将对象变成字典
        return model_to_dict(obj.user, fields=['id', 'nickname', 'avatar'])

    def get_topic(self, obj):
        if not obj.topic:
            return

        return model_to_dict(obj.topic, fields=['id', 'title'])


class NewsDetailViewModel(serializers.ModelSerializer):
    images = serializers.SerializerMethodField()
    create_date = serializers.DateTimeField(format="%Y-%m-%d %H:%M")
    topic = serializers.SerializerMethodField()
    viewer = serializers.SerializerMethodField()
    comment = serializers.SerializerMethodField()
    user = serializers.SerializerMethodField()
    favor = serializers.SerializerMethodField()

    class Meta:
        model = models.News
        # fields = "__all__"
        exclude = ['cover']

    def get_images(self, obj):
        detail_queryset = models.NewsDetail.objects.filter(news=obj)
        return [model_to_dict(row, ['id', 'cos_path']) for row in detail_queryset]

    def get_topic(self, obj):
        if not obj.topic:
            return
        return model_to_dict(obj.topic, fields=['id', 'title'])

    def get_viewer(self, obj):
        viewer_queryset = models.ViewerRecord.objects.filter(news=obj).order_by('-id')
        return [model_to_dict(row.user, fields=['nickname', 'id', 'avatar']) for row in viewer_queryset]

    def get_user(self, obj):
        # 将对象变成字典
        return model_to_dict(obj.user, fields=['id', 'nickname', 'avatar'])

    def get_comment(self, obj):
        # 获取所有一级评论
        comment_queryset = models.CommentRecord.objects.filter(news=obj, depth=1).order_by("-id").values(
            'id',
            'content',
            'depth',
            'user__avatar',
            'create_date',
            'user__nickname'
        )

        comment_id_list = [item['id'] for item in comment_queryset]
        # 获取一级评论和最早回复的二级评论id
        result = models.CommentRecord.objects \
            .filter(news=obj, depth=2, reply_id__in=comment_id_list) \
            .values('reply_id').annotate(max_id=Max('id'))
        # 获取最早回复的二级评论id
        second_id_list = [item['max_id'] for item in result]
        # 获取二级评论的所有信息
        second_queryset = models.CommentRecord.objects.filter(news=obj, id__in=second_id_list).values(
            'id',
            'content',
            'depth',
            'user__avatar',
            'create_date',
            'reply_id',
            'reply__user__nickname',
            'user__nickname'
        )
        data_list = {}
        user_object = self.context['request'].user

        # 认证不通过执行

        if not user_object:
            for item in comment_queryset:
                item['favor'] = False
                item['create_date'] = item['create_date'].strftime("%Y-%m-%d %H:%M")
                data_list[item['id']] = item
            for row in second_queryset:
                row['create_date'] = row['create_date'].strftime("%Y-%m-%d %H:%M")
                row['favor'] = False
                data_list[row['reply_id']]['child'] = [row]
            return data_list.values()
        else:
            for item in comment_queryset:
                item['favor'] = models.CommentFavorRecord.objects.filter(comment_id=item['id'],
                                                                         user=user_object).exists()
                item['create_date'] = item['create_date'].strftime("%Y-%m-%d %H:%M")
                data_list[item['id']] = item
            for row in second_queryset:
                row['create_date'] = row['create_date'].strftime("%Y-%m-%d %H:%M")
                row['favor'] = models.CommentFavorRecord.objects.filter(comment_id=row['id'], user=user_object).exists()
                data_list[row['reply_id']]['child'] = [row]
            return data_list.values()

    def get_favor(self, obj):
        user = self.context['request'].user
        # 如果用户没登录不能看点赞
        if not user:
            return False
        # 判断是否有赞
        exists = models.NewsFavorRecord.objects.filter(user=user, news=obj).exists()
        return exists


class FavorModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.NewsFavorRecord
        fields = ["news"]


class ChildFavorModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.CommentFavorRecord
        fields = ["comment"]
